/* samplecb.c
A C programming example of interfacing with the
LINDO API that employs a callback function.
The problem:
MAX = 20 * A + 30 * C
S.T. A + 2 * C <= 120
A <= 60
C <= 50
Solving such a problem with the LINDO API involves
the following steps:
1. Create a LINDO environment.
2. Create a model in the environment.
3. Specify the model.
4. Perform the optimization.
5. Retrieve the solution.
6. Delete the LINDO environment.
*/
#include
#include
/* LINDO API header file */
#include "lindo.h"
/* license.h must be edited to include the license key
that came with your software */
#include "license.h"
/* Define a macro to declare variables for
error checking */
#define APIERRORSETUP \
int nErrorCode; \
char cErrorMessage[LS_MAX_ERROR_MESSAGE_LENGTH] \
/* Define a macro to do our error checking */
#define APIERRORCHECK \
if (nErrorCode) \
{ \
if ( pEnv) \
{ \
LSgetErrorMessage( pEnv, nErrorCode, \
cErrorMessage); \
printf("Errorcode=%d: %s\n", nErrorCode, \
cErrorMessage); \
} else {\
printf( "Fatal Error\n"); \
} \
exit(1); \
} \
/* A callback function that will be called by the LINDO
solver */
int CALLBACKTYPE MyCallback( pLSmodel pMod, int nLocation,
void* pMyData)
{
/* Display the string we passed to LSsetCallback() */
printf( "In MyCallback: %s\n", pMyData);
/* Display current iteration count and objective value */
{
int nIter;
double dObj;
LSgetCallbackInfo( pMod, nLocation, LS_IINFO_ITER,
&nIter);
LSgetCallbackInfo( pMod, nLocation, LS_DINFO_POBJ,
&dObj);
printf( "In MyCallback, Iters, Obj: %d %g\n",
nIter, dObj);
}
return( 0);
}
/* main entry point */
void main()
{
APIERRORSETUP;
/* Number of constraints */
int nM = 3;
/* Number of variables */
int nN = 2;
/* declare an instance of the LINDO environment object */
pLSenv pEnv;
/* declare an instance of the LINDO model object */
pLSmodel pModel;
/* >>> Step 1 <<< Create a LINDO environment. Note:
MY_LICENSE_KEY must be defined in license.h to
be the license key shipped with your software. */
pEnv = LScreateEnv ( &nErrorCode, MY_LICENSE_KEY);
if ( nErrorCode == LSERR_NO_VALID_LICENSE)
{
printf( "Invalid License Key!\n");
exit( 1);
}
APIERRORCHECK;
/* >>> Step 2 <<< Create a model in the environment. */
pModel = LScreateModel ( pEnv, &nErrorCode);
APIERRORCHECK;
{
/* >>> Step 3 <<< Specify the model.
To specify our model, we make a call to LSloadLPData,
passing it:
- A pointer to the model which we are specifying(pModel)
- The number of constraints in the model
- The number of variables in the model
- The direction of the optimization (i.e. minimize or
- maximize)
- The value of the constant term in the objective (may
be zero)
- The coefficients of the objective function
- The right-hand sides of the constraints
- The types of the constraints
- The number of nonzeros in the constraint matrix
- The indices of the first nonzero in each column
- The length of each column
- The nonzero coefficients
- The row indices of the nonzero coefficients
- Simple upper and lower bounds on the variables
*/
/* The direction of optimization */
int nDir = LS_MAX;
/* The objective's constant term */
double dObjConst = 0.;
/* The coefficients of the objective function */
double adC[2] = { 20., 30.};
/* The right-hand sides of the constraints */
double adB[3] = { 120., 60., 50.};
/* The constraint types */
char acConTypes[3] = {'L', 'L', 'L'};
/* The number of nonzeros in the constraint matrix */
int nNZ = 4;
/* The indices of the first nonzero in each column */
int anBegCol[3] = { 0, 2, nNZ};
/* The length of each column. Since we aren't leaving
any blanks in our matrix, we can set this to NULL */
int *pnLenCol = NULL;
/* The nonzero coefficients */
double adA[4] = { 1., 1., 2., 1.};
/* The row indices of the nonzero coefficients */
int anRowX[4] = { 0, 1, 0, 2};
/* Simple upper and lower bounds on the variables.
By default, all variables have a lower bound of zero
and an upper bound of infinity. Therefore pass NULL
pointers in order to use these default values. */
double *pdLower = NULL, *pdUpper = NULL;
/* We have now assembled a full description of the model.
We pass this information to LSloadLPData with the
following call. */
nErrorCode = LSloadLPData( pModel, nM, nN, nDir,
dObjConst, adC, adB, acConTypes, nNZ, anBegCol,
pnLenCol, adA, anRowX, pdLower, pdUpper);
APIERRORCHECK;
}
{
/* Establish the callback function */
char* pMyData = "My string!";
nErrorCode = LSsetCallback( pModel,
(cbFunc_t) MyCallback, pMyData);
APIERRORCHECK;
/* >>> Step 4 <<< Perform the optimization */
nErrorCode = LSoptimize( pModel,
LS_METHOD_PSIMPLEX);
APIERRORCHECK;
}
{
/* >>> Step 5 <<< Retrieve the solution */
int i;
double adX[ 2], dObj;
/* Get the value of the objective */
LSgetObjective( pModel, &dObj) ;
APIERRORCHECK;
printf( "Objective Value = %g\n", dObj);
/* Get the variable values */
nErrorCode = LSgetPrimalSolution ( pModel, adX);
APIERRORCHECK;
printf ("Primal values = ");
for (i = 0; i < nN; i++) printf( "%g ", adX[i]);
printf ("\n");
}
/* >>> Step 6 <<< Delete the LINDO environment */
LSdeleteEnv( pEnv);
}
|